package aimis.dto;

import lombok.Data;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import aimis.constant.ResponseEnum;

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

@Data
public class Result {
    private Result() {

    }

    private Map<String, Object> data = new HashMap<>();

    private Integer code;
    private String message;
    private boolean success;
    private Map<String, Object> errors = new HashMap<>();

    public Result add(String key, Object value) {
        data.put(key, value);
        return this;
    }

    public Result setErrors(Map map) {
        errors = map;
        return this;
    }

    public static Result success(String message, Integer code) {
        var result = new Result();
        result.setCode(code);
        result.setSuccess(true);
        result.setMessage(message);
        return result;
    }

    public static Result success(String message) {
        return success(message, ResponseEnum.OK.value());
    }

    public static Result success(ResponseEnum r) {
        var res = new Result();
        res.setCode(r.value());
        res.setSuccess(true);
        res.setMessage(r.getMsg());
        return res;
    }

    public static Result success() {
        return success(ResponseEnum.OK);
    }

    public static Result error(String message, Integer code, BindingResult bindingResult) {
        var result = new Result();
        result.setCode(code);
        result.setSuccess(false);
        result.setMessage(message);
        if (bindingResult != null && bindingResult.hasErrors())
            result.errors = bindingResult.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
        return result;
    }

    public static Result error(String message, Integer code) {
        return error(message, code, null);
    }

    public static Result error(String message) {
        return error(message, 0, null);
    }

    public static Result error() {
        return error(null, 0, null);
    }

    public static Result error(ResponseEnum r) {
        var res = new Result();
        res.setCode(r.value());
        res.setSuccess(false);
        res.setMessage(r.getMsg());
        return res;
    }

    public static Result error(String message, BindingResult bindingResult) {
        return error(message, 0, bindingResult);
    }

    public static Result error(BindingResult bindingResult) {
        return error(null, 0, bindingResult);
    }

    public static Result exception(String message) {
        var result = new Result();
        result.setCode(-1);
        result.setSuccess(false);
        result.setMessage(message);
        return result;
    }

    public static Result exception() {
        return exception(null);
    }


}
